//
//  HOMFastTrampoline.m
//  HigherOrderMessaging
//
//  Created by Ofri Wolfus on 21/05/06.
//  Copyright 2006 Ofri Wolfus. All rights reserved.
//

#import "HOMFastTrampoline.h"
#include <objc/objc-runtime.h>
#include <malloc/malloc.h>


@implementation HOMFastTrampoline

+ (id)trampolineWithTarget:(id)aTarget selector:(SEL)aSelector {
	return [[self alloc] initWithTarget:aTarget selector:aSelector lifeTime:1U];
}

+ (id)trampolineWithTarget:(id)aTarget selector:(SEL)aSelector lifeTime:(unsigned)numberOfMessages {
	return [[self alloc] initWithTarget:aTarget selector:aSelector lifeTime:numberOfMessages];
}

- (id)initWithTarget:(id)aTarget selector:(SEL)aSelector {
	return [self initWithTarget:aTarget selector:aSelector lifeTime:1U];
}

//Designated initializer
- (id)initWithTarget:(id)aTarget selector:(SEL)aSelector lifeTime:(unsigned)numberOfMessages {
	target = [aTarget retain];
	selector = aSelector;
	lifeTime = numberOfMessages;
	//messages.message_list = (lifeTime > 1U ? malloc(sizeof(HOMMessage) * lifeTime) : NULL);
	//messages.count = 0;
	
	return self;
}

- (void)dealloc {
	[target release];
	//if (messages.message_list)
	//	free(messages.message_list);
	
	[super dealloc];
}

/*- (id)forward:(SEL)sel :(marg_list)args {
	if (messages.count == 0 && lifeTime == 1U) {	//No need to copy the arguments if we need them only now
		[self autorelease];
		return objc_msgSend(target, selector, sel, args);
	}
	
	Class		cls = [target class];
	Method		m = class_getInstanceMethod(cls, sel);
	marg_list	list;
	
	if (!m)	//The method is not an instance method but perhaps it's a class method
		m = class_getClassMethod(cls, sel);
	
	if (!m)	//The method is not a class method either. We give our target a last chance to provide us with a method
		m = [target objcMethodForSelector:sel];
	
	if (!m) {	//We didn't manage to get the info we needed, so we just give up and return nil
		[self autorelease];
		return nil;
	}
	
	//Save our method
	messages.message_list[messages.count].method = m;
	
	//Allocate memory for our args list, and copy it
	//messages.message_list[messages.count].args = memcpy(malloc(length), args, length);
	marg_malloc(messages.message_list[messages.count].args, m);
	list = messages.message_list[messages.count].args;
	memcpy(list, args, malloc_size(list));
	
	++messages.count;
	
	if (messages.count == lifeTime) {
		[self autorelease];
		return objc_msgSend(target, selector, &messages);
	} else
		return self;
}*/

- (id)forward:(SEL)sel :(marg_list)args {
	[self autorelease];
	return objc_msgSend(target, selector, sel, args);
}

@end
